package com.ncmem.up6.sql;

import org.apache.commons.lang.StringUtils;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SqlWhere {
    /// <summary>
    /// 字段列表，默认判断操作=,a=@a
    /// </summary>
    Map<String,SqlParam> m_params;
    /// <summary>
    /// 条件SQL语句
    /// </summary>
    Map<String, String> m_sqls;

    public SqlWhere() {
        this.m_params = new HashMap<String,SqlParam>();
        this.m_sqls = new HashMap<String, String>();
    }
    public static SqlWhere build() { return new SqlWhere(); }

    /// <summary>
    /// 增加SQL语句
    /// </summary>
    /// <param name="n"></param>
    /// <param name="v"></param>
    /// <returns></returns>
    public SqlWhere sql(String n, String v) {
        if(StringUtils.isEmpty(v)) return this;
        if (this.m_sqls.containsKey(n))
        {
            this.m_sqls.put(n,v);
        }
        else this.m_sqls.put(n, v);
        return this;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name">字段名称</param>
    /// <param name="value">字段值</param>
    public SqlWhere eq(String name,String value)
    {
        this.m_params.put(name,new SqlParam(name,value));
        return this;
    }
    public SqlWhere ineq(String name, String value)
    {
        this.m_params.put(name, new SqlParam(name, value,"!="));
        return this;
    }
    public SqlWhere eq(String name, Boolean value)
    {
        this.m_params.put(name, new SqlParam(name, value));
        return this;
    }

    public SqlWhere ineq(String name, Boolean value)
    {
        this.m_params.put(name, new SqlParam(name, value,"!="));
        return this;
    }

    public SqlWhere eq(String name, int value)
    {
        this.m_params.put(name, new SqlParam(name, value));
        return this;
    }

    /**
     * 转换为条件声明语句：name=@name and age=@age
     * @param op and
     * @return
     */
    public String toSql(String op) {
        List<String> sqls = new ArrayList<String>();

        //sql参数转成条件
        for(Object k : this.m_params.keySet())
        {
            SqlParam p = this.m_params.get(k );
            //a=@a,a=:a
            sqls.add(String.format("%s%s?",
                    p.m_name,
                    p.pre,//操作符号，默认：=
                    p.getParamterName()));
        }

        //添加sql语句
        for(Object k : this.m_sqls.keySet())
        {
            sqls.add(this.m_sqls.get(k));
        }

        String sql = StringUtils.join(sqls.toArray(new String[sqls.size()])," "+op+" ");
        return sql;
    }

    /**
     * 转换为完整条件语句：where a=@a and b=@b and c=@c
     * @param op and
     * @return
     */
    public String toSqlWhere(String op) {
        if (this.empty()) return "";
        return " where "+this.toSql(op);
    }

    public SqlParam[] toArray() {
        List<SqlParam> sqls = new ArrayList<SqlParam>();
        for(Object k : this.m_params.keySet())
        {
            sqls.add(this.m_params.get(k));
        }
        return sqls.toArray(new SqlParam[sqls.size()]);
    }

    public Boolean empty() {
        return this.m_params.size()== 0&&this.m_sqls.size()==0;
    }

    /// <summary>
    /// 将参数值绑定到列
    /// </summary>
    /// <param name="table"></param>
    /// <param name="cmd"></param>
    public void bind(SqlTable table, PreparedStatement cmd) throws SQLException, ParseException {
        SqlParam[] ps = table.mergeVal(this.toArray());
        int column=1;
        for(int i = 0 ; i < ps.length;++i)
        {
            ps[i].bind(cmd,column++);
        }
    }

    /**
     * 绑定参数
     * @param table
     * @param cmd
     * @param index 列索引
     * @throws SQLException
     * @throws ParseException
     */
    public void bind(SqlTable table, PreparedStatement cmd,int index) throws SQLException, ParseException {
        SqlParam[] ps = table.mergeVal(this.toArray());
        int column=index;
        for(int i = 0 ; i < ps.length;++i)
        {
            ps[i].bind(cmd,column++);
        }
    }
}
